package com.xayy.core.antlr4.utils;

import cn.kawins.base.utils.BeanUtil;
import com.xayy.core.antlr4.enums.ValueTypeEnum;
import com.xayy.core.antlr4.exception.CheckSyntaxException;
import com.xayy.core.antlr4.model.ErrorResult;
import com.xayy.core.antlr4.visitor.HealthEvaluateVisitor;
import com.xayy.mgt.model.FunctionalIndicators;
import com.xayy.mgt.model.HealthSituation;
import com.xayy.mgt.service.FunctionalIndicatorsService;
import com.xayy.mgt.service.HealthSituationService;
import com.xayy.mgt.service.impl.OutInterfaceServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.Date;

/**
 * @author Nie
 * @version V1.0
 * @date 2023/8/16 15:08
 */
@Component
@Slf4j
public class GnUtil {

    private static GnUtil gnUtil;

    @Autowired
    private FunctionalIndicatorsService funService;
    @Autowired
    private HealthSituationService healthSituationService;

    @PostConstruct
    public void init() {
        gnUtil = this;
        gnUtil.funService = this.funService;
        gnUtil.healthSituationService = this.healthSituationService;
    }

    public static Double getGnScore(Long satelliteId, Long nodeId, Date evaluationTime, String name,
        Boolean checkSyntax, Boolean errorEvaluation) {
        String code = name.substring(4);
        // 先从缓存中获取有没有
        Double vaule;
        if (Boolean.TRUE.equals(errorEvaluation)) {
            vaule = Golabl.getErrorVaule(satelliteId, nodeId, code, ValueTypeEnum.GN_VALUES.getKey());
        } else {
            vaule = Golabl.getVaule(satelliteId, nodeId, code, ValueTypeEnum.GN_VALUES.getKey());
        }
        if (vaule != null)
            return vaule;
        // 调用脚本计算
        // 查询该条性能参数信息获取执行语法
        FunctionalIndicators functionalIndicators =
            gnUtil.funService.selectOne(FunctionalIndicators.builder().nodeId(nodeId).metricsCode(code).build());
        if (BeanUtil.isEmpty(functionalIndicators)){
            log.error("功能项:" + name + ",不存在");
            throw new CheckSyntaxException("功能项:" + name + ",不存在");
        }
        String customParam = functionalIndicators.getCustomParam();
        HealthEvaluateVisitor visitor =
            new HealthEvaluateVisitor(satelliteId, nodeId, evaluationTime, checkSyntax, errorEvaluation);
        ErrorResult execute = FunUtil.execute(customParam, visitor);
        if (execute.isSuccess()) {
            Double result = execute.getResult();
            if (Boolean.FALSE.equals(checkSyntax)) {
                if (Boolean.TRUE.equals(errorEvaluation)) {
                    Golabl.setErrorValue(satelliteId, nodeId, code, result, ValueTypeEnum.GN_VALUES.getKey());
                } else {
                    Golabl.setValue(satelliteId, nodeId, code, result, ValueTypeEnum.GN_VALUES.getKey());
                    insertInfo(nodeId, evaluationTime, result, functionalIndicators);
                }
            }
            OutInterfaceServiceImpl.addLogs("功能项："+functionalIndicators);
            OutInterfaceServiceImpl.addLogs("功能项计算结果："+result);
            return result;
        }
        return 0D;
    }

    /**
     * 更新节点评分以及增加评分记录
     * 
     * @param nodeId
     *            节点id
     * @param evaluationTime
     *            评估时间
     * @param result
     *            评估结果
     * @param functionalIndicators
     *            指标项
     */
    private static void insertInfo(Long nodeId, Date evaluationTime, Double result,
        FunctionalIndicators functionalIndicators) {
        // 更新节点评分以及增加评分记录
        functionalIndicators.setTimeInfo(evaluationTime);
        functionalIndicators.setDataInfo(result.toString());
        functionalIndicators.setUpdatedTime(new Date());
        gnUtil.funService.updateById(functionalIndicators);

        HealthSituation healthSituation = new HealthSituation();
        healthSituation.setNodeId(nodeId);
        healthSituation.setMetricsId(functionalIndicators.getId());
        healthSituation.setMetricsName(functionalIndicators.getMetricsName());
        healthSituation.setMetricsType(1);
        healthSituation.setTimeInfo(evaluationTime);
        healthSituation.setDataInfo(result.toString());
        healthSituation.setCreatedTime(new Date());
        gnUtil.healthSituationService.insert(healthSituation);
    }
}
